home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Add-On
/
Workbench Add-On - Volume 1.iso
/
BBS-Archive
/
DiskUtil
/
Info
/
FreeSpace.lha
/
FreeSpace.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-08-28
|
12KB
|
326 lines
/*
FreeSpace - graphically displays free space for each mounted volume
Copyright 1993 Barry McConnell
bmccnnll@unix1.tcd.ie
*/
#include <exec/execbase.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <graphics/gfxbase.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
#include <graphics/text.h>
#include <libraries/gadtools.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/intuition.h>
#include <proto/graphics.h>
#include <proto/gadtools.h>
#include <proto/icon.h>
#include <stdio.h>
#include <string.h>
#define TEXTLENGTH 36 /* max length of volume statistics */
struct volume /* to store volume data */
{
struct volume *next;
struct volume *prev;
char *name; /* name of volume */
char *text; /* statistics in ASCII */
LONG free, used, percentage;
};
static UBYTE *version = "$VER: FreeSpace 1.0 (27.08.93)";
extern struct ExecBase *SysBase;
UWORD osver = 0; /* Kickstart version */
UWORD __chip waitPointer[] =
{
0x0000, 0x0000,
0x0400, 0x07c0,
0x0000, 0x07c0,
0x0100, 0x0380,
0x0000, 0x07e0,
0x07c0, 0x1ff8,
0x1ff0, 0x3fec,
0x3ff8, 0x7fde,
0x3ff8, 0x7fbe,
0x7ffc, 0xff7f,
0x7efc, 0xffff,
0x7ffc, 0xffff,
0x3ff8, 0x7ffe,
0x3ff8, 0x7ffe,
0x1ff0, 0x3ffc,
0x07c0, 0x1ff8,
0x0000, 0x07e0,
0x0000, 0x0000,
};
/*
Display a busy pointer in the current window, and prevent user from
clicking on any gadgets.
*/
void busyPointer(struct Window *myWindow, struct Requester *myReq)
{
InitRequester(myReq);
Request(myReq, myWindow);
if (osver < 39)
SetPointer(myWindow, waitPointer, 16, 16, -6, 0);
else
SetWindowPointer(myWindow, WA_BusyPointer, TRUE,
WA_PointerDelay, TRUE,
TAG_END);
}
/*
Restore the pointer to normal.
*/
void normalPointer(struct Window *myWindow, struct Requester *myReq)
{
ClearPointer(myWindow);
EndRequest(myReq, myWindow);
}
/*
Compare two strings. Like "strcmp" but case-insensitive.
*/
int Compare(char *s, char *t)
{
for (; ((*s & ~32) == (*t & ~32)) && *s; s++, t++) /* sorry, K&R ;-) */
;
return (*s & ~32) - (*t & ~32);
}
/*
Alphabetically insert "node" into "list".
*/
void Sort(struct List *list, struct volume *node)
{
struct volume *temp = (struct volume *)list -> lh_Head;
while (temp -> next && Compare(temp -> name, node -> name) < 0)
temp = temp -> next;
Insert(list, (struct Node *)node, (struct Node *)temp -> prev);
}
void main(int argc, char *argv[])
{
struct DiskObject *myIcon;
struct Screen *myScreen;
struct Window *myWindow;
struct Requester tinyReq;
struct VisualInfo *visInfo;
struct TextFont *propFont;
struct TextExtent fontSize;
struct RastPort myRast, *winRast;
struct DosList *dl;
struct InfoData info;
struct Remember *memoryKey;
struct List volumeList;
struct IntuiMessage *message;
struct volume *volume;
int maxNameLen = 0, maxTextLen = 0, count = 0, memOkay = TRUE, tempLen,
winLeft = 0, winTop = 0, winWidth, winHeight, pen = 3, title, gap, rectSize;
ULONG class, code;
UWORD height;
BYTE i,j;
BPTR lock;
char **tools, *string, *myName, *name, *dest, freeSuffix, usedSuffix;
struct EasyStruct about =
{
sizeof(struct EasyStruct),
0,
"About FreeSpace",
"FreeSpace v1.0 -- Freely Distributable\nCopyright 1993 Barry McConnell\nbmccnnll@unix1.tcd.ie\n\nDedicated to Niall Murphy :-)",
"Okay"
};
IntuitionBase = NULL;
DOSBase = NULL;
GfxBase = NULL;
GadToolsBase = NULL;
osver = SysBase -> LibNode.lib_Version; /* running under 2.0, 3.0, ...? */
if (IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37))
if (DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37))
if (GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37))
if (GadToolsBase = OpenLibrary("gadtools.library", 37))
if (IconBase = OpenLibrary("icon.library", 37))
{
if (!argc) /* only look at ToolTypes if started from Workbench */
{
myName = ((struct WBStartup *)argv) -> sm_ArgList -> wa_Name; /* find ourselves */
if (myIcon = GetDiskObject(myName)); /* read in .info file */
{
tools = myIcon -> do_ToolTypes;
if (string = FindToolType(tools, "LEFT"))
sscanf(string, "%d", &winLeft);
if (string = FindToolType(tools, "TOP"))
sscanf(string, "%d", &winTop);
if (string = FindToolType(tools, "PEN"))
sscanf(string, "%d", &pen);
FreeDiskObject(myIcon);
}
}
myScreen = LockPubScreen(NULL); /* get a lock on the Workbench screen */
visInfo = GetVisualInfo(myScreen, TAG_END); /* GadTools needs this */
propFont = OpenFont(myScreen -> Font);
FontExtent(propFont, &fontSize); /* figure out pixel size of fonts */
height = fontSize.te_Height;
InitRastPort(&myRast); /* dummy RastPort for getting string lengths */
SetFont(&myRast, propFont);
memoryKey = NULL;
volumeList.lh_Head = (struct Node *)&volumeList.lh_Tail;
volumeList.lh_Tail = NULL;
volumeList.lh_TailPred = (struct Node *)&volumeList.lh_Head;
dl = LockDosList(LDF_VOLUMES | LDF_READ);
while ((dl = NextDosEntry(dl, LDF_VOLUMES)) && memOkay) /* walk through list of volumes */
{
if ((volume = AllocRemember(&memoryKey, sizeof(struct volume), MEMF_ANY))
&& (volume -> text = AllocRemember(&memoryKey, TEXTLENGTH, MEMF_ANY)))
{
name = (char *)BADDR(dl -> dol_Name); /* BCPL string */
i = *((BYTE *)name); /* length */
dest = volume -> name = AllocRemember(&memoryKey, i+2, MEMF_ANY);
for (j = 1; i; i--)
*(dest++) = name[j++];
*(dest++) = ':';
*(dest) = 0;
lock = Lock(volume -> name, ACCESS_READ); /* get a lock on this volume */
*(--dest) = 0; /* remove trailing colon */
Info(lock, &info);
freeSuffix = usedSuffix = 'K'; /* default */
volume -> free = (info.id_NumBlocks - info.id_NumBlocksUsed) * info.id_BytesPerBlock / 1024;
volume -> used = info.id_NumBlocksUsed * info.id_BytesPerBlock / 1024;
volume -> percentage = info.id_NumBlocksUsed * 100 / info.id_NumBlocks;
if (volume -> free > 9999)
{
volume -> free = volume -> free / 1024; /* move up to MB */
freeSuffix = 'M';
}
if (volume -> used > 9999)
{
volume -> used = volume -> used / 1024;
usedSuffix = 'M';
}
sprintf(volume -> text, "%d%% full, %d%c free, %d%c in use", volume -> percentage, volume -> free, freeSuffix, volume -> used, usedSuffix);
SetSoftStyle(&myRast, FSF_BOLD, FSF_BOLD);
tempLen = TextLength(&myRast, volume -> name, j-1);
if (maxNameLen < tempLen)
maxNameLen = tempLen;
SetSoftStyle(&myRast, NULL, FSF_BOLD); /* turn off bold */
tempLen = TextLength(&myRast, volume -> text, strlen(volume -> text));
if (maxTextLen < tempLen)
maxTextLen = tempLen;
Sort(&volumeList, volume);
UnLock(lock);
count++;
}
else
memOkay = FALSE;
}
UnLockDosList(LDF_VOLUMES | LDF_READ);
if (memOkay)
{
title = (myScreen -> WBorTop) + height + 1 + INTERHEIGHT;
gap = title + propFont -> tf_Baseline;
winWidth = INTERWIDTH*2 + maxTextLen;
winHeight = title + count * (height*2 + INTERHEIGHT*3) - INTERHEIGHT + 2; /* allow a couple of pixels for the comma */
if (myWindow = OpenWindowTags(NULL, WA_Title, "FreeSpace",
WA_Left, winLeft,
WA_Top, winTop,
WA_Width, winWidth,
WA_Height, winHeight,
WA_DragBar, TRUE,
WA_DepthGadget, TRUE,
WA_CloseGadget, TRUE,
WA_Activate, TRUE,
WA_RMBTrap, TRUE,
WA_IDCMP, IDCMP_CLOSEWINDOW | RAWKEY,
WA_PubScreen, myScreen,
TAG_END))
{
volume = (struct volume *)volumeList.lh_Head;
winRast = myWindow -> RPort;
SetFont(winRast, propFont); /* defaults to GfxBase -> DefaultFont, which is not what we want */
for (i = 0; i < count; volume = volume -> next, i++)
{
SetAPen(winRast, 1); /* black */
Move(winRast, INTERWIDTH, gap + i * (height*2 + INTERHEIGHT*3));
SetSoftStyle(winRast, FSF_BOLD, FSF_BOLD);
Text(winRast, volume -> name, strlen(volume -> name));
Move(winRast, INTERWIDTH, gap + height + INTERHEIGHT + i * (height*2 + INTERHEIGHT*3));
SetSoftStyle(winRast, NULL, FSF_BOLD);
Text(winRast, volume -> text, strlen(volume -> text));
DrawBevelBox(winRast, (INTERWIDTH*3) / 2 + maxNameLen, title + i * (height*2 + INTERHEIGHT*3),
winWidth - maxNameLen - (INTERWIDTH*5) / 2, height,
GTBB_Recessed, TRUE,
GT_VisualInfo, visInfo,
TAG_END);
SetAPen(winRast, pen); /* pen to fill with (user's choice) */
rectSize = winWidth - maxNameLen - INTERWIDTH*3;
rectSize = (rectSize * volume -> percentage) / 100;
RectFill(winRast, (INTERWIDTH*3) / 2 + maxNameLen + 2, title + i * (height*2 + INTERHEIGHT*3) + 1,
(INTERWIDTH*3) / 2 + maxNameLen + 1 + rectSize, title + i * (height*2 + INTERHEIGHT*3) + height - 2);
}
do
{
WaitPort(myWindow -> UserPort);
if (message = (struct IntuiMessage *)GetMsg(myWindow -> UserPort))
class = message -> Class, code = message -> Code;
ReplyMsg((struct Message *)message);
if (class == RAWKEY && code == 95) /* Help key */
{
busyPointer(myWindow, &tinyReq);
EasyRequest(NULL, &about, NULL, NULL);
normalPointer(myWindow, &tinyReq);
}
}
while (!(class == IDCMP_CLOSEWINDOW));
CloseWindow(myWindow);
}
}
FreeRemember(&memoryKey, TRUE);
CloseFont(propFont);
FreeVisualInfo(visInfo);
UnlockPubScreen(NULL, myScreen);
}
CloseLibrary(GadToolsBase); /* safe to pass NULL */
CloseLibrary((struct Library *)GfxBase);
CloseLibrary((struct Library *)DOSBase);
CloseLibrary((struct Library *)IntuitionBase);
}